
/*
 *  Copyright (C) 2011 Naveed Quadri
 *  naveedmurtuza@gmail.com
 *  www.naveedmurtuza.blogspot.com
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package org.gpl.SwingComponents.ColumnManager;


import java.util.Hashtable;
import javax.swing.DefaultListModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.gpl.SwingComponents.JCheckboxList.CheckBoxListItem;
import org.gpl.SwingComponents.SwingUtils.SwingUtils;

/**
 * Displays a Windows like dialog to select which columns to show/hide,resize and reorder columns 
 * @author Naveed Quadri
 */
public class ChooseColumnsDlg extends javax.swing.JDialog implements ListSelectionListener {
    public enum Direction {
        UP,
        DOWN
    };
    private final TableColumnChooser columnManager;
    private Hashtable<String, Integer> columnSizeChanged;

    /** Creates new form ChooseColumnsDlg */
    public ChooseColumnsDlg(java.awt.Frame parent, boolean modal, TableColumnChooser columnManager) {
        super(parent, modal);
        initComponents();
        checkBoxList1.addListSelectionListener(this);
        this.columnManager = columnManager;
        columnSizeChanged = new Hashtable<String, Integer>();

    }

    @Override
    public void setVisible(boolean b) {
        if (b) {
            String colHeader;
            CheckBoxListItem item;
            for (int i = 0; i < checkBoxList1.getModel().getSize(); i++) {
                item = (CheckBoxListItem) checkBoxList1.getModel().getElementAt(i);
                colHeader = item.getValue().toString();
                if (columnManager.IsColumnVisible(colHeader)) {
                    item.setSelected(true);
                } else {
                    item.setSelected(false);
                }
            }
        }
        columnSizeChanged.clear();
        super.setVisible(b);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        moveUpBtn = new javax.swing.JButton();
        moveDownBtn = new javax.swing.JButton();
        cancelBtn = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        jSpinner1 = new javax.swing.JSpinner();
        jSeparator1 = new javax.swing.JSeparator();
        okBtn = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        checkBoxList1 = new org.gpl.SwingComponents.JCheckboxList.JCheckBoxList();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Choose Details"); // NOI18N
        setName("Form"); // NOI18N

        jLabel1.setText("Select the details you want to display."); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        jLabel2.setText("Details:"); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N

        moveUpBtn.setText("Move Up"); // NOI18N
        moveUpBtn.setName("moveUpBtn"); // NOI18N
        moveUpBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveUpBtnActionPerformed(evt);
            }
        });

        moveDownBtn.setText("Move Down"); // NOI18N
        moveDownBtn.setName("moveDownBtn"); // NOI18N
        moveDownBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                moveDownBtnActionPerformed(evt);
            }
        });

        cancelBtn.setText("Cancel"); // NOI18N
        cancelBtn.setName("cancelBtn"); // NOI18N
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }
        });

        jLabel3.setText("Width of selected column(pixels):"); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N

        jSpinner1.setName("jSpinner1"); // NOI18N
        jSpinner1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner1StateChanged(evt);
            }
        });

        jSeparator1.setName("jSeparator1"); // NOI18N

        okBtn.setText("OK"); // NOI18N
        okBtn.setName("okBtn"); // NOI18N
        okBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okBtnActionPerformed(evt);
            }
        });

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        checkBoxList1.setName("checkBoxList1"); // NOI18N
        jScrollPane1.setViewportView(checkBoxList1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jSpinner1, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE))
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 216, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(moveUpBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(moveDownBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(okBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cancelBtn)))
                .addContainerGap())
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelBtn, okBtn});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addGap(18, 18, 18)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(moveUpBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(moveDownBtn))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 235, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3)
                    .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelBtn)
                    .addComponent(okBtn))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

        public void valueChanged(ListSelectionEvent evt) {
        if (evt.getValueIsAdjusting()) {
            return;
        }
        int selectedIndex = checkBoxList1.getSelectedIndex();
        toggleButtonVisibility();

        CheckBoxListItem selectedItem = (CheckBoxListItem) checkBoxList1.getModel().getElementAt(selectedIndex);
        String columnName = selectedItem.toString();
        if (columnManager.IsColumnVisible(columnName)) {
            int size = columnManager.getColumnWidth(columnName);
            if(columnSizeChanged.containsKey(columnName))
                size = columnSizeChanged.get(columnName);
            jSpinner1.setValue(size);
        } else {
            jSpinner1.setValue(0);
        }
    }

    private void toggleButtonVisibility() {
        int selectedIndex = checkBoxList1.getSelectedIndex();
        moveUpBtn.setEnabled(true);
        moveDownBtn.setEnabled(true);
        if (selectedIndex == 0) {
            moveUpBtn.setEnabled(false);
            moveDownBtn.setEnabled(true);
        }
        int listSizeZeroBased = checkBoxList1.getModel().getSize() - 1;
        if (selectedIndex == listSizeZeroBased) {
            moveUpBtn.setEnabled(true);
            moveDownBtn.setEnabled(false);
        }
    }

    private void okBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okBtnActionPerformed
        String colHeader;
        CheckBoxListItem item;
        columnManager.hideAllColumns();
        for (int i = 0; i < checkBoxList1.getModel().getSize(); i++) {
            item = (CheckBoxListItem) checkBoxList1.getModel().getElementAt(i);
            colHeader = item.toString();
            columnManager.toggleColumnVisibility(colHeader, item.isSelected());
            if (columnSizeChanged.containsKey(colHeader) && columnManager.IsColumnVisible(colHeader)) {
                columnManager.setColumnWidth(colHeader, columnSizeChanged.get(colHeader));
            }

        }
        columnSizeChanged.clear();
        setVisible(false);
    }//GEN-LAST:event_okBtnActionPerformed

    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
        setVisible(false);        // TODO add your handling code here:
    }//GEN-LAST:event_cancelBtnActionPerformed

    private void moveUpBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveUpBtnActionPerformed
        checkBoxList1.removeListSelectionListener(this);
        SwingUtils.moveListItemUp(checkBoxList1, checkBoxList1.getSelectedIndex());
        toggleButtonVisibility();
        checkBoxList1.addListSelectionListener(this);
    }//GEN-LAST:event_moveUpBtnActionPerformed

    private void moveDownBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveDownBtnActionPerformed
        checkBoxList1.removeListSelectionListener(this);
        SwingUtils.moveListItemDown(checkBoxList1, checkBoxList1.getSelectedIndex());
        toggleButtonVisibility();
        checkBoxList1.addListSelectionListener(this);
    }//GEN-LAST:event_moveDownBtnActionPerformed

    private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner1StateChanged
        String identifier = ((CheckBoxListItem) checkBoxList1.getSelectedValue()).getText();
        if (identifier != null) {
            if (columnSizeChanged.containsKey(identifier)) {
                columnSizeChanged.remove(identifier);
            }
            columnSizeChanged.put(identifier, Integer.parseInt(jSpinner1.getValue().toString()));

        }
    }//GEN-LAST:event_jSpinner1StateChanged

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                ChooseColumnsDlg dialog = new ChooseColumnsDlg(new javax.swing.JFrame(), true, null);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelBtn;
    private org.gpl.SwingComponents.JCheckboxList.JCheckBoxList checkBoxList1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSpinner jSpinner1;
    private javax.swing.JButton moveDownBtn;
    private javax.swing.JButton moveUpBtn;
    private javax.swing.JButton okBtn;
    // End of variables declaration//GEN-END:variables

    public void setColumns(String[] cols) {
        DefaultListModel model = new DefaultListModel();
        for (int i = 0; i < cols.length; i++) {
            model.addElement(new CheckBoxListItem(cols[i], columnManager.IsColumnVisible(cols[i])));
        }
        checkBoxList1.setModel(model);
    }
}
